package com.jf3q.iot.utils;

import com.sun.deploy.util.StringUtils;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * 电表工具类
 */
public class ElectricityMeterUtil {

    /**
     * 获取完整指令字符串
     * @param hexAddress 设备地址
     * @param constant 校验前的指令内容 InstructConstant类中获取
     * @return
     */
    public static String getCompleteInstruct(String hexAddress,String constant){
        String instructTxt = constant.replaceAll("FE","").trim();
        String addressInstaruct = MessageFormat.format(instructTxt,hexAddress);
        //获取校验码
        String ten = getCSCheck(addressInstaruct);
        return MessageFormat.format(constant,hexAddress)+" "+ten+" 16";
    }



    /**
     * 设备地址的转换
     * 转化前 000000920245
     * 转换后 45 02 92 00 00 00
     * @param deviceNo
     * @return
     */
    public static String deviceAddressConvert(String deviceNo){
        String resultDeviceNo = null;
        if(deviceNo!=null){
            deviceNo=deviceNo.replace("", " ");
            int num = deviceNo.length()/4;
            LinkedList<String> items = new LinkedList<String>();
            String newStr;
            for(int i=0;i<num;i++){
                newStr="";
                newStr = deviceNo.substring(0, 4);
                deviceNo = deviceNo.substring(4);
                items.addFirst(newStr.replaceAll(" ", ""));
            }
            resultDeviceNo = StringUtils.join(items," ");
        }
        return resultDeviceNo;
    }
    /**
     * 获取指令中的校验码
     * @param hexStr
     * @return
     */
    public static String getCSCheck(String hexStr) {
        byte[] bytes = fromHexString(hexStr);
        int ck = 0;
        for(byte b : bytes){
            ck = ck+b;
        }
        //去除FE后，从帧起始符68H到数据域 全部字符的字节相加取模256，
        //保留一直字节，超过256会有多个字节所以要取模
        Integer a  = ck%0x100;
        System.out.println("检验码的和是："+ toHex(ck));
        String b = toHex(a);
        if(b.length()<2){
            b="0"+b;
        }
        if(b.length()>2){
            b= b.substring(b.length()-2);
        }
        return b;
    }

    /**
     * 转换为十六进制数据
     * @param num
     * @return
     */
    public static String toHex(int num) {
        char[] map = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
        if (num == 0)
            return "0";
        String result = "";
        while (num != 0) {
            int x = num & 0xF;
            result = map[(x)] + result;
            num = (num >>> 4);
        }
        return result;
    }

    /**
     * 16进制数据转字节数组
     *
     * @param hexStr
     * @return
     */
    public static byte[] fromHexString(String hexStr) {
        if (hexStr.length() < 1)
            return null;
        hexStr = hexStr.replaceAll(" ", "");
        byte[] result = new byte[hexStr.length() / 2];
        for (int i = 0; i < hexStr.length() / 2; i++) {
            int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
            int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
            result[i] = (byte) (high * 16 + low);
        }
        return result;

    }

    /**
     * 将字节转换成16进制字符串
     * @param raw
     * @return
     */
    public static String getBufHexStr(byte[] raw) {
        String HEXES = "0123456789ABCDEF";
        if (raw == null) {
            return null;
        }
        final StringBuilder hex = new StringBuilder(2 * raw.length);
        for (final byte b : raw) {
            hex.append(HEXES.charAt((b & 0xF0) >> 4))
                    .append(HEXES.charAt((b & 0x0F)));
        }
        return hex.toString();
    }

    /**
     * 设备地址的转换
     * 转化前 45 02 92 00 00 00
     * 转换后 000000920245
     * @param deviceNo
     * @return
     */
    public static String addressConvertNo(String deviceNo,boolean isContinuityStr){
        String resultDeviceNo = null;
        if(deviceNo!=null){
            if(isContinuityStr)
                deviceNo = hexAddcharacter(deviceNo," ");
            String[] deviceNos = deviceNo.split(" ");
            LinkedList<String> items = new LinkedList<String>();
            for(int i=deviceNos.length;i>0;i--){
                items.addLast(deviceNos[i-1]);
            }
            resultDeviceNo = StringUtils.join(items," ").replaceAll(" ","");
        }
        return resultDeviceNo;
    }

    /**
     * 给16进制的字符串添加指定字符
     * @param str
     * @return
     */
    public static String hexAddcharacter(String str,String character){
        char[] chars = str.toCharArray();
        StringBuffer sb = new StringBuffer();
        for(int i=0;i<chars.length;i++){
            if(i%2!=0){
                sb.append(chars[i-1]).append(chars[i]).append(character);
            }
        }
        return sb.toString().substring(0,sb.toString().lastIndexOf(character));
    }

    /**
     * 数据域接收时减33
     * @param haxData
     * @return
     */
    public static String dataAreaSubtract33(String haxData){
        String resultStr = null;
        if(haxData!=null){
            //获取到单个数据数组
            String[] singles = haxData.split(" ");
            List<String> list = new ArrayList<>();
            for(int i=0;i<singles.length;i++){
                list.add(makeCheckSubtract(singles[i]+" 33"));
            }
            resultStr = StringUtils.join(list," ");
        }
        return resultStr;
    }

    /**
     * 数据域发送时加33
     * @param haxData
     * @return
     */
    public static String dataAreaPlus33(String haxData){
        String resultStr = null;
        if(haxData!=null){
            //获取到单个数据数组
            String[] singles = haxData.split(" ");
            List<String> list = new ArrayList<>();
            for(int i=0;i<singles.length;i++){
                list.add(makeChecksum(singles[i]+" 33"));
            }
            resultStr = StringUtils.join(list," ");
        }
        return resultStr;
    }

    /**
     * 十六进制求和
     *
     * @param hexdata
     *            00 1E
     * @return
     */
    public static String makeChecksum(String hexdata) {
        if (hexdata == null || hexdata.equals("")) {
            return "00";
        }
        hexdata = hexdata.replaceAll(" ", "");
        int total = 0;
        int len = hexdata.length();
        if (len % 2 != 0) {
            return "00";
        }
        int num = 0;
        while (num < len) {
            String s = hexdata.substring(num, num + 2);
            total += Integer.parseInt(s, 16);
            num = num + 2;
        }
        return hexInt(total);
    }

    /**
     * 十六进制求差
     *
     * @param hexdata
     *            00 1E
     * @return
     */
    public static String makeCheckSubtract(String hexdata) {
        if (hexdata == null || hexdata.equals("")) {
            return "00";
        }
        hexdata = hexdata.replaceAll(" ", "");
        int total = 0;
        int len = hexdata.length();
        if (len % 2 != 0) {
            return "00";
        }
        int num = 0;
        ;
        while (num < len) {
            String s = hexdata.substring(num, num + 2);
            if(num==0){
                total += Integer.parseInt(s, 16);
            }else{
                total -= Integer.parseInt(s, 16);
            }
            num = num + 2;
        }
        return hexInt(total);
    }
    private static String hexInt(int total) {
        int a = total / 256;
        int b = total % 256;
        if (a > 255) {
            return hexInt(a) + format(b);
        }
        if(org.springframework.util.StringUtils.isEmpty(format(a) + format(b))){
            return "00";
        }
        return format(a) + format(b);
    }
    private static String format(int hex) {
        if(hex==0) return "";
        String hexa = Integer.toHexString(hex);
        int len = hexa.length();
        if (len < 2) {
            hexa = "0" + hexa;
        }

        return hexa.toUpperCase();
    }
}
